<template>
	<div class="color-hue-slider" :class="{ 'is-vertical': vertical }">
		<div ref="bar" class="color-hue-slider__bar" @click="handleClick"></div>
		<div ref="thumb" class="color-hue-slider__thumb" :style="{
			left: thumbLeft + 'px',
			top: thumbTop + 'px'
		}"></div>
	</div>
</template>

<script setup lang="ts">
import draggable from '../util/draggable'
import type { Nullable } from '../color-picker'
import { HueSliderProps } from "../color-picker";

const props = defineProps(HueSliderProps);
const instance = getCurrentInstance()

const thumb = ref<Nullable<HTMLElement>>(null) //管理thumb
const bar = ref<Nullable<HTMLElement>>(null) //管理bar
const thumbLeft = ref(0) 
const thumbTop = ref(0)

/**
* 计算hueValue
*/
let hueValue = computed(() => props.color.get('hue'))

/**
* 监听hueValue值
*/
watch(
	() => hueValue.value,
	() => {
		update()
	}
)

/**
 * handleClick点击事件
 * @param event
 */
const handleClick = (event: Event) => {
	const target = event.target
	if (target !== thumb.value) {
		handleDrag(event)
	}
}

/**
 * handleDrag拖拽事件
 * @param event
 */
const handleDrag = (event: any) => {
	const ele = instance?.vnode.el as HTMLElement
	const rect = ele.getBoundingClientRect()
	let hue
	if (!props.vertical) {
		let left = event.clientX - rect.left
		left = Math.min(left, rect.width - (thumb.value as HTMLElement).offsetWidth / 2)
		left = Math.max((thumb.value as HTMLElement).offsetWidth / 2, left)

		hue = Math.round(
			((left - (thumb.value as HTMLElement).offsetWidth / 2) /
				(rect.width - (thumb.value as HTMLElement).offsetWidth)) *
			360
		)
	} else {
		let top = event.clientY - rect.top

		top = Math.min(top, rect.height - (thumb.value as HTMLElement).offsetHeight / 2)
		top = Math.max((thumb.value as HTMLElement).offsetHeight / 2, top)
		hue = Math.round(
			((top - (thumb.value as HTMLElement).offsetHeight / 2) /
				(rect.height - (thumb.value as HTMLElement).offsetHeight)) *
			360
		)
	}
	props.color.set('hue', hue)
}

/**
 * 获取Thumb左侧
 */
const getThumbLeft = (): number => {
	const ele = instance?.vnode.el as HTMLElement

	if (props.vertical) return 0
	const hue = props.color.get('hue')

	if (!ele) return 0
	return Math.round(
		(hue * (ele.offsetWidth - (thumb.value as HTMLElement).offsetWidth / 2)) / 360
	)
}

/**
 * 获取Thumb顶部
 */
const getThumbTop = (): number => {
	const ele = instance?.vnode.el as HTMLElement
	if (!props.vertical) return 0
	const hue = props.color.get('hue')

	if (!ele) return 0
	return Math.round(
		(hue * (ele.offsetHeight - (thumb.value as HTMLElement).offsetHeight / 2)) / 360
	)
}

/**
 * update更新事件
 */
const update = () => {
	thumbLeft.value = getThumbLeft()
	thumbTop.value = getThumbTop()
}
defineExpose({ update });
onMounted(() => {
	const dragConfig = {
		drag: (event: any) => {
			handleDrag(event)
		},
		end: (event: any) => {
			handleDrag(event)
		}
	}
	draggable(bar.value as HTMLElement, dragConfig)
	draggable(thumb.value as HTMLElement, dragConfig)
	update()
})
</script>

